import BaseCom from "../common/BaseCom";
import Utils from "../common/Util";
import GameManager from "../common/GameManager";
import { ScoreObjPool } from "../common/ScoreObjPool";
import PropManager from "../game/PropManager";
import PopUpManager from "../common/PopUpManager";
import LangManager from "../i18n/LangManager";
import AudioManager from "../common/AudioManager";
import FacebookStorage from "../Facebook/FacebookStorage";
import Facebook from "../Facebook/Facebook";
import Logger from "../Logger/Logger";
import Gmbox from "../gmbox/Gmbox";
import EventUtils from "../gmbox/EventUtils";

// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const { ccclass, property } = cc._decorator;

@ccclass
export default class UILayer extends BaseCom {
    //当前分数
    @property(cc.Node)
    curScoreNode: cc.Node;

    @property(cc.Label)
    highestScore: cc.Label;

    //暂停按钮
    @property(cc.Node)
    pauseBtn: cc.Node;

    //重新生成节点
    @property(cc.Node)
    reproduceBtn: cc.Node;

    //重新生成节点
    @property(cc.Label)
    reproduceBtnLabel: cc.Label;

    @property(cc.Node)
    //万能块节点
    universalNode: cc.Node;

    //重新生成节点
    @property(cc.Label)
    universalNodeLabel: cc.Label;

    @property([cc.Integer])
    flyTrasureChestTime: number[] = [];

    private _manager: GameManager;
    /**暂停界面 */
    private _pauseLayer: cc.Node;
    @property(cc.Node)
    //超越谁谁谁节点
    rankNode: cc.Node;

    private _FlyTrasureChest: cc.Node;
    private _FlyTrasureChestIndex = 0;
    private _FlyTrasureChestTimeId;

    private _BannerAd = null;
    private _BannerAdRetryCount = 0;
    private _BannerAdRetryId;

    onLoad() {
        this.initFlyTrasureChest();
        this.initBannerAd();
    }

    onEnable() {
        super.onShow();

        this._manager = GameManager.getInstance();

        Utils.addEventListener(this.pauseBtn, this.pauseBtnClicked.bind(this));
        this._manager.eventCenter.RegisterEvent(this.uuid, "readArchive", this.readArchive.bind(this));
        this._manager.eventCenter.RegisterEvent(this.uuid, "score_update", this.scoreUpdateHandler.bind(this));
        this._manager.eventCenter.RegisterEvent(this.uuid, "block_score_update", this.blockScoreUpdateHandler.bind(this));
        this._manager.eventCenter.RegisterEvent(this.uuid, "restart", this.restartHandler.bind(this));
        this._manager.eventCenter.RegisterEvent(this.uuid, "gameover", this.restartHandler.bind(this));
        this._manager.eventCenter.RegisterEvent(this.uuid, "propChange", this.propChangeHandler.bind(this));
        this._manager.eventCenter.RegisterEvent(this.uuid, "getProp", this.getPropHandler.bind(this));
        this._manager.eventCenter.RegisterEvent(this.uuid, "highest_score_changed", this.refreshHighestScoreHandler.bind(this));

        this.reproduceBtn.on(cc.Node.EventType.TOUCH_START, this.reproduceHandler, this);
        this.universalNode.on(cc.Node.EventType.TOUCH_START, this.removeBlockHandler, this);
        // this.readArchive();
        this.propChangeHandler();
        this.refreshHighestScoreHandler();
    }
    onDisable() {
        super.onHide();
        Utils.removeEventListener(this.pauseBtn);
        this._manager.eventCenter.RemoveEvent(this.uuid);
        Utils.removeEventListener(this.reproduceBtn);
        this.reproduceBtn.off(cc.Node.EventType.TOUCH_START, this.reproduceHandler, this);
        this.universalNode.off(cc.Node.EventType.TOUCH_START, this.removeBlockHandler, this);
    }

    private restartHandler(): void {
        this.setCurrentScoreText("0")
        this.rankNode.active = false;
        PropManager.getInstance().reset();
        this.propChangeHandler();
        this._FlyTrasureChestIndex = 0;
        this.initFlyTrasureChest();
        this._BannerAdRetryCount = 0;
        this.initBannerAd();
    }

    private propChangeHandler() {
        let propManager = PropManager.getInstance();
        this.reproduceBtnLabel.string = "x" + propManager.propNum[1] + "";
        this.universalNodeLabel.string = "x" + propManager.propNum[2] + "";
    }

    private getPropHandler(data): void {
        let targetPos: cc.Vec2;
        let propNode: cc.Node = data.node;
        propNode.parent = cc.find("Canvas");
        let pos: cc.Vec2 = propNode.parent.convertToNodeSpaceAR(data.pos);
        propNode.setPosition(pos);
        if (data.type == 0) {
        } else if (data.type == 1) {
            targetPos = this.reproduceBtn.parent.convertToWorldSpaceAR(this.reproduceBtn.position);
        } else {
            targetPos = this.universalNode.parent.convertToWorldSpaceAR(this.universalNode.position);
        }
        targetPos = propNode.parent.convertToNodeSpaceAR(targetPos);
        data.fade();
        propNode.runAction(cc.sequence(cc.delayTime(1), cc.moveTo(0.8, targetPos).easing(cc.easeSineIn()), cc.callFunc(() => {
            propNode.removeAllChildren();
            propNode.getComponent(cc.Sprite).spriteFrame = null;
            let audioManager: AudioManager = GameManager.getInstance().audioManager;
            audioManager.playEffect("shourubaoxiang");
            Utils.AddAutoRemoveEffect(propNode, 'prefab/back_light_motion', "hb", () => {
                data.cb();
                propNode.destroy();
            }, this);
        })))
        // type: propType,
        // node: propNode
    }

    /**
     * 读取存档
     */
    private readArchive(): void {
        let data = this._manager.gameData.onReadGameArchive();
        if (data) {
            let score = data.cur_score || 0;
            this.setCurrentScoreText(score);
            if (score > 0 && this.rankNode) {
                this.rankNode.active = true;
            }
            GameManager.getInstance().eventCenter.DispatchEvent("updateScore", score);
            if (data.received_props) {
                PropManager.getInstance().propNum = data.received_props;
                this.propChangeHandler();
            }
        }

    }

    private refreshHighestScoreHandler() {
        if (Facebook.IsFBInit()) {
            FacebookStorage.LoadDataFormFB(['highestScore'], (data) => {
                let highestScore = data['highestScore'];
                console.log("refreshHighestScore " + highestScore)
                if (highestScore) {
                    this.highestScore.string = highestScore;
                }
            })
        } else {
            this.highestScore.string = "" + GameManager.getInstance().gameLocalData.ReadLocalHighestScore();
        }
    }

    //点击暂停按钮
    pauseBtnClicked() {
        EventUtils.logEvent("click_settings")
        GameManager.getInstance().audioManager.PlayBtnSound();
        Utils.GetPrefab("prefab/PauseLayer.prefab", (prefab) => {
            if (prefab && (!this._pauseLayer || !this._pauseLayer.parent)) {
                this._pauseLayer = cc.instantiate(prefab);
                if (this._pauseLayer) {
                    this.node.addChild(this._pauseLayer);
                }
            }
        }, this);
    }

    private userScoreNum: number = 0;
    private myNewScore: number = 0;
    private scoreUpdateHandler(): void {
        //用户成绩刷新
        this.userScoreNum = this._manager.gameData.GetCurScore();
        this.myNewScore = parseInt(this.curScoreNode.getComponent(cc.Label).string);
        this.schedule(this.runChangeUserScore, 0.05);
        if (this.rankNode && !this.rankNode.active) {
            this.rankNode.active = true;
        }

        // this.curScoreNode.getComponent(cc.Label).string = this._manager.gameData.GetCurScore() + "";
    }

    private blockScoreUpdateHandler(evt: any): void {
        this.showScore(evt.pos, evt.score);
    }

    /**
     * 刷新按钮
     */
    private reproduceHandler(): void {
        let hasFinger = PropManager.getInstance().propNum[1] > 0
        EventUtils.logEvent("click_finger", {
            has_finger: hasFinger
        })
        if (!hasFinger) {
            //PopUpManager.textTips(this.node.parent, LangManager.getStrByKey("propTip"));
            let successCallback = () => {
                PropManager.getInstance().changeProp(PropManager.TYPE_FINGER, 1);
            }
            if (Gmbox.RewardedVideoAd) {
                Gmbox.RewardedVideoAd.showRewardedVideoAd(successCallback);
            } else {
                Facebook.FBPropAd.showRewardedVideoAd(successCallback);
            }

            return;
        }
        GameManager.getInstance().eventCenter.DispatchEvent("refresh_dragdata")
    }

    private removeBlockHandler(): void {
        let hasHammer = PropManager.getInstance().propNum[2] > 0
        EventUtils.logEvent("click_hammer", {
            has_hammer: hasHammer
        })
        if (!hasHammer) {
            //PopUpManager.textTips(this.node.parent, LangManager.getStrByKey("propTip"));
            let successCallback = () => {
                PropManager.getInstance().changeProp(PropManager.TYPE_HAMMER, 1);
            }
            if (Gmbox.RewardedVideoAd) {
                Gmbox.RewardedVideoAd.showRewardedVideoAd(successCallback);
            } else {
                Facebook.FBPropAd.showRewardedVideoAd(successCallback);
            }
            return;
        }
        GameManager.getInstance().eventCenter.DispatchEvent("removeBlock")
    }

    //显示分数特效
    private async showScore(pos, score, callback = null) {
        if (Utils.IsArray(pos) == false) {
            pos = [pos];
        }

        if (Utils.IsArray(score) == false) {
            score = [score];
        }

        for (var i = 0; i < pos.length; i++) {
            var posItem = pos[i];
            var scoreItem = `+${score[i]}`;
            var myposItem = this.node.convertToNodeSpaceAR(posItem);
            var scoreNode = await ScoreObjPool.GetScoreObj();
            if (scoreNode) {
                var scoreCom = Utils.GetComponent(scoreNode, "ScoreCom");
                if (scoreCom) {
                    if (i == (pos.length - 1)) {
                        scoreCom.showScore(myposItem, scoreItem, callback);
                    } else {
                        scoreCom.showScore(myposItem, scoreItem, null);
                    }
                }
                this.node.addChild(scoreNode);
            }
        }
    }

    //用户成绩动态变化
    private runChangeUserScore() {
        //开始时的分数
        var tempScore = parseInt(this.curScoreNode.getComponent(cc.Label).string);
        //结束时的分数
        var endedScore = this.userScoreNum;
        //console.log("runChangeUserScore  tempScore  " + tempScore + " this.userScoreNum  " + this.userScoreNum);
        //用户增加的成绩
        var changedScore = endedScore - tempScore;
        //分数增加的时间系数
        var changeTime = 0.016;
        if (changedScore > 10) {
            if (changedScore > 0) {
                if (endedScore == 0) {
                    tempScore -= this.myNewScore * changeTime;
                }
                else {
                    tempScore += changedScore / 10;
                }
            }
            else if (changedScore < 0) {
                if (endedScore == 0) {
                    tempScore -= this.myNewScore * changeTime;
                }
                else {
                    tempScore -= Math.abs(endedScore) * changeTime;
                }
            }
            if (endedScore < 0 && endedScore - tempScore >= 0) {
                tempScore = endedScore;
            }
            if (endedScore > 0 && tempScore - endedScore >= 0) {
                tempScore = endedScore;
            }
            this.setCurrentScoreText((tempScore >> 0).toString())
        }
        else {
            this.setCurrentScoreText((endedScore >> 0).toString())
            this.unschedule(this.runChangeUserScore);
        }
    }

    private setCurrentScoreText(score) {
        this.curScoreNode.getComponent(cc.Label).string = ` ${score} `;
    }

    private initFlyTrasureChest() {
        if (this._FlyTrasureChestIndex >= this.flyTrasureChestTime.length) return;
        clearTimeout(this._FlyTrasureChestTimeId);
        let timeOut = this.flyTrasureChestTime[this._FlyTrasureChestIndex];
        Logger.log("initFlyTrasureChest timeOut = " + timeOut);
        this._FlyTrasureChestTimeId = setTimeout(() => {
            cc.loader.loadRes("prefab/FlyTrasureChest", cc.Prefab, (err, prefab) => {
                if (prefab && (!this._FlyTrasureChest || !this._FlyTrasureChest.parent)) {
                    this._FlyTrasureChest = cc.instantiate(prefab);
                    this._FlyTrasureChest.x = 0;
                    this._FlyTrasureChest.y = 0;
                    this._FlyTrasureChest.parent = this.node;
                    this._FlyTrasureChest.getComponent("FlyTrasureChest").mTrasureChestIndex = this._FlyTrasureChestIndex += 1;
                    var anim = Utils.GetComponent(this._FlyTrasureChest, cc.Animation);
                    if (anim) {
                        anim.play(name);
                    }
                    Logger.log("initFlyTrasureChest show");
                    this._FlyTrasureChestIndex += 1;
                }
                this.initFlyTrasureChest();
            });
        }, timeOut * 60 * 1000)
    }

    private initBannerAd() {
        clearTimeout(this._BannerAdRetryId);
        if (this._BannerAd != null) {
            this._BannerAd.destroy();
        }
        this._BannerAd = Gmbox.createGmboxBannerAd();
        this._BannerAd.show();
        this._BannerAd.onLoad(() => {
            Logger.log('Banner广告加载成功')
            this._BannerAdRetryId = setTimeout(() => {
                this._BannerAdRetryCount = 0;
                Logger.log('Banner重新加载新广告');
                this.initBannerAd();
            }, 5 * 60 * 1000);
        })
        this._BannerAd.onError(err => {
            Logger.log("Banner 失败 ：", err)
            this._BannerAdRetryCount++;
            if (this._BannerAdRetryCount > 3) {
                Logger.error("Banner失败次数过多")
                return;
            }
            this._BannerAdRetryId = setTimeout(() => {
                this.initBannerAd();
            }, 10000 * this._BannerAdRetryCount);
        })
    }


    // update (dt) {}
}
